package org.misty.seckill.util;

import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

import static org.misty.seckill.constant.Names.COOKIE_NAME_TOKEN;

public class ServletUtil {
  public static String getCookie(HttpServletRequest request, String name) {
    if (request == null || request.getCookies() == null || StringUtils.isEmpty(name)) {
      return null;
    }
    return Arrays.stream(request.getCookies())
        .filter(cookie -> name.equals(cookie.getName()))
        .findFirst()
        .map(Cookie::getValue)
        .orElse(null);
  }

  public static void addCookie(HttpServletResponse response, String name, String value, int maxAgeInSec, String path) {
    var cookie = new Cookie(name, value);
    cookie.setMaxAge(maxAgeInSec);
    cookie.setPath(path);
    response.addCookie(cookie);
  }

  public static String readSessionToken(HttpServletRequest request) {
    var headerToken = request.getHeader(COOKIE_NAME_TOKEN);
    var paramToken = request.getParameter(COOKIE_NAME_TOKEN);
    var cookieToken = ServletUtil.getCookie(request, COOKIE_NAME_TOKEN);
    return ArgsUtil.notEmpty(headerToken, paramToken, cookieToken).orElse(null);
  }

  public static void writeSessionToken(HttpServletResponse response, String token, int expiryInSec, String path) {
    ServletUtil.addCookie(response, COOKIE_NAME_TOKEN, token, expiryInSec, path);
    response.addHeader(COOKIE_NAME_TOKEN, token);
  }

  public static boolean isHtmlRequest(HttpServletRequest request) {
    var accept = request.getHeader("Accept");
    return accept != null && accept.contains("text/html");
  }

  public static boolean isAjaxRequest(HttpServletRequest request) {
    var accept = request.getHeader("Accept");
    if (accept != null && accept.contains("application/json")) {
      return true;
    }

    var xRequestedWith = request.getHeader("X-Requested-With");
    if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
      return true;
    }

    return false;
  }
}
